home *** CD-ROM | disk | FTP | other *** search
- {
- From: "CLAUS FISCHER" <WI00227@wipool.wifo.uni-mannheim.de>
-
- I had found the Extend.Pas and PExted.pas on SWAG.
- First provides 255 File in DOS, second in protcted mode.
- Now I had mixed them together and I wish to give this to
- SWAG. Where should I post this?
-
- (*** 3 Files: ***)
- 255DEMO.PAS (Extend Version with StdErr)
- FILEPLUS.PAS (was EXTEND.PAS)
- DOSMEM.PAS (was SHRINK.PAS)
- {-------------------------------snipp--------------------------------}
- program Test255Files;
-
- uses fileplus, { <--- This is the magic line that does
- everything }
- Dos;
-
- const MaxCount = 255;
-
- type FileArray = array[1..MaxCount] of text;
-
- var Count: integer;
- StdErr: Text;
- F: ^FileArray;
- I: integer;
- Num: string[6];
-
- procedure stderror(var f:text);
- var
- tmpfile:text;
- begin
- assign(tmpfile,''); (* stdoutput *)
- rewrite(tmpfile);
- move(tmpfile, f, sizeof(f));
- textrec(f).handle:= 2;
- close(tmpfile);
- end;
-
- begin
- write('Hello!! I''m running under ');
- {$IFDEF MSDOS}writeln('MsDos REAL-Mode');
- {$ELSE} writeln('DPMI Protected Mode');
- {$ENDIF}
- new(F); { Use heap because of large size of this array }
- writeln('Opening files...');
- Stderror(StdErr);
- writeln( Stderr, '(Handle Stderr) ',TextRec(StdErr).Handle );
- writeln( Output, '(Handle Stdout) ',TextRec(Output).Handle );
- write( Output, '(Handle:FileNo) ');
- I := 0;
- repeat
- inc(I);
- str(I,Num);
- assign(F^[I],'junk' + num + '.txt');
- {$I-}
- rewrite(F^[I]);
- write( OutPut, i:4,':',TextRec(f^[i]).Handle );
- {$I+}
- until ioresult <> 0;
- writeln(output);
- Count := I - 1;
- writeln('Successfully opened ', Count, ' files at the same time.
- Writing to each file...');
- for I := 1 to Count do
- writeln(F^[I], 'This is a test.');
- writeln('Closing and erasing each file...');
- for I := 1 to Count do
- begin
- close(F^[I]);
- erase(F^[I])
- end;
- writeln('Done.')
- end.
- {----------------------snapp----------------------------------------}
-
- {---------------------snipp---------------------------------------}
- {$I-,O-,R-}
-
- unit fileplus; {origin name Extend}
-
- {Patch V1.0 94-12 Claus Fischer for}
- {REF: MsDos-Real-Mode: Scott Bussinger}
- { DPMI: : Kim Kokkonen, TurboPower Software}
- { catched up on SIMTEL-Archieve and SWAG-List}
-
- {FILEPLUS Patch Claus Fischer}
- { Changes:
- Main feater: Use Real-Mode and DPMI-Mode with the same Unit.
- I have disabled DOS 2.xx Management because its not necessary for
- me.
- The SHRINK-Unit is now named as DosMem.Pas.
- The futur check of MSDOS-Version is removed, because further MSDOS
- vers
- will shure support the prefix features. The market use this.
- The DPMIExtendHandles-Function was changed to Procedure, so its
- equal
- to MSDOSExtendHandles (not neccesary, but looks pretty).
- Claus Fischer
- WI00227@WIPOOL.WIFO.UNI-MANNHEIM.DE
- }
-
- {EXTEND Version Scott Bussinger}
- { This unit allows a program to open more than the standard DOS
- maximum of 20
- open files at one time. You must also be sure to set a FILES=XX
- statement
- in your CONFIG.SYS file.
- (DISABLED: This program installs a special interrupt handler
- under DOS 2.x, some semi-documented features under
- DOS 3.x prior to DOS 3.3 and the DOS extend files
- call under DOS 3.3 or later. C.F.)
- This unit USES the DOS unit and should be used BEFOR ANY OTHER UNTIS
- other than the DOS unit. This code was based upon earlier work by
- Randy Forgaard, Bela Lubkin and Kim Kokkonen. See EXTEND.DOC for
- more information.
-
- Scott Bussinger
- Professional Practice Systems
- 110 South 131st Street
- Tacoma, WA 98444
- (206)531-8944
- Compuserve [72247,2671] }
-
- { ** Revision History **
- 1 EXTEND.PAS 9-Mar-89,`SCOTT' First version using TLIB -- Based on
- 3.2
- 2 EXTEND.PAS 15-Sep-89,`SCOTT'
- Added SwapVectorsExtend procedure
- Put handle table into DOS memory
- Use DOS 3.3 extended handles function when available
- 3 EXTEND.PAS 2-Oct-89,`SCOTT'
- Fixed bug in determining the DOS version
- 4 EXTEND.PAS 5-Oct-89,`SCOTT'
- Yet another bug in the DosVersion detection
- 5 EXTEND.PAS 19-Nov-90,`SCOTT'
- New version of EXTEND that is compatible with Turbo Pascal
- 6.0
- Modified the documentation and version numbers to be less
- confusing
- ** Revision History ** }
-
- {PEXTEND DPMI-Version Kim Kokkonen
- ------------------------------------------------------------------
- This unit provides a single function, DpmiExtendHandles, for
- extending the file handle table for DOS protected mode applications
- under Borland Pascal 7.0.
-
- The standard DOS call for this purpose (AH = $67) does odd things to
- DOS memory when run from a BP7 pmode program. If you Exec from a
- program that has extended the handle table, DOS memory will be
- fragmented, leaving a stranded block of almost 64K at the top of DOS
- memory. The function implemented here avoids this problem.
-
- If you haven't used an ExtendHandles function before, note that you
- cannot get more handles than the FILES= statement in CONFIG.SYS
- allows. (Other utilities such as FILES.COM provided with QEMM do the
- same thing.) However, even if you have FILES=255, any single program
- cannot open more than 20 files (and DOS uses up 5 of those) unless
- you use a routine like DpmiExtendHandles. This routine allows up to
- 255 open files as long as the FILES= statement provides for them.
-
- This code works only for DOS 3.0 or later. Since (to my knowledge)
- DPMI cannot be used with earlier versions of DOS, the code doesn't
- check the DOS version.
-
- Don't call this function more than once in the same program.
-
- Version 1.0,
- Written 12/15/92, Kim Kokkonen, TurboPower Software
- }
-
- interface
-
- (* delted(0) of Dos 2.11 Version-Managament *)
- (* procedure SwapVectorsExtend;
- { Swap interrupt vectors taken over by Extend unit with system
- vectors }
- *)
- (* END of delted(0) *)
-
- implementation
-
- uses Dos,
- {$IFDEF MSDOS} DosMem;
- {$ELSE} WinApi;
- {$ENDIF}
-
- (* deleted(1) DOS 2.11 Ver ... *)
- (* var ExitSave: pointer; { Previous exit
- procedure }
- OldInt21: pointer; { Save old INT 21 }
- *)
- (* END of delted(1) *)
-
- (* Deleted(2) ... DOS 2.11 Ver *)
- (*
- {$L EXTEND }
- procedure ExtendInit; external; { Initialize
- interrupt handler }
- procedure ExtendHandler; external; { Replacement INT 21
- handler }
- *)
- (* End of delted(2) *)
-
- (* ... deleted(3) DOS 2.11 Ver.... *)
- (*
- procedure SwapVectorsExtend;
- { Swap interrupt vectors taken over by Extend unit with system
- vectors }
- var TempVector: pointer;
- begin
- if lo(DosVersion) = 2 then
- begin
- GetIntVec($21,TempVector); { Swap the INT 21
- vectors }
- SetIntVec($21,OldInt21);
- OldInt21 := TempVector
- end
- end;
- *)
- (* END of Deleted(3) *)
-
-
- {$IFDEF MSDOS}
- procedure MSDOSExtendHandles;
- (* My Patch of MSDOS Scott Bussinger Version *)
- { Install the extended handles interrupt. No files (other than
- standard handles) should be open when unit starts up. }
-
- type HandleArray = array[0..254] of byte; { Room for 255
- handles }
- HandleArrayPtr = ^HandleArray;
-
- var Regs: Registers;
- DosMemory: pointer; { Pointer to
- memory gained from DOS }
- OldHandleTable: HandleArrayPtr; { Pointer to
- original table }
- OldNumHandles: byte; { Original number
- of handles }
- begin
-
- if lo(DosVersion) <= 2
- then {Patch KISS!} exit;
-
- (* deleted(4) DOS 2.11 ..... *)
- (*
- begin
- GetIntVec($21,OldInt21); { Install interrupt
- handler under DOS 2.x }
- ExtendInit; { Initialize the
- interrupt handler }
- SetIntVec($21,@ExtendHandler)
- end
- else
- *)
- (* END of deleted(4) *)
-
- (* deleted(5) schnick-schnack: MickySoft will support further *)
- (*
- if (lo(DosVersion)>=4) or (hi(DosVersion)>=30) { Does this DOS
- version support the handles call? }
- then
- begin
- DosDispose(DosMemory); { Free up the DOS memory
- block so that the next function will succeed }
- with Regs do
- begin
- AH := $67; { Tell DOS to allow
- us 255 handles }
- BX := 255; { KEEP THIS NUMBER
- ODD TO AVOID BUG IN SOME VERSIONS OF DOS 3.3!! }
- MsDos(Regs)
- end
- end
- else begin
- *)
- (* END of delted(5) *)
-
-
- DosNewShrink(DosMemory,sizeof(HandleArray));
- if DosMemory = nil then exit;
- { There wasn't enough memory for a handle table, so just quit }
- begin {else}
-
- { Initialize new handles as unused *1* }
- { Get old table length *2* }
- { Save address of old table *3* }
- { Set new table length *4* }
- { Point to new handle table *5* }
- { Copy the current handle table to the new handle table *6* }
-
- fillchar(DosMemory^,sizeof(HandleArray),$FF); (*1*)
- OldNumHandles := mem[prefixseg:$0032]; (*2*)
- OldHandleTable := pointer(ptr(prefixseg,$0034)^); (*3*)
- mem[prefixseg:$0032] := sizeof(HandleArray); (*4*)
- pointer(meml[prefixseg:$0034]) := DosMemory; (*5*)
- move(OldHandleTable^,DosMemory^,OldNumHandles) (*6*)
- end
- end; (* of MSDOSExtenHandles *)
- {$ENDIF} {of IFDEF MSDOS}
-
- {$IFNDEF MSDOS} {.= WINAPI}
- procedure DPMIExtendHandles;
- const Handles = 255; (* added *)
- (* My Patch of MSDOS Kim Kokkonen Version *)
- (* Orginal was: function DpmiExtendHandles(Handles : Byte) : Word; *)
- type DosMemRec = record
- Sele, Segm : Word;
- end;
- var
- OldTable : Pointer;
- OldSize : Word;
- NewTable : Pointer;
- DosMem : DosMemRec;
- begin
- (* DEL: DpmiExtendHandles := 0; PROCEDURE replaced *)
- (* DEL: if Handles <= 20 then Exit; CONST replaced *)
-
- {Allocate new table area in DOS memory}
- LongInt(DosMem) := GlobalDosAlloc(Handles);
- if LongInt(DosMem) = 0 then
- exit; (* add *)
-
- (* DEL: begin DpmiExtendHandles := 8;Exit; end; PROCEDURE
- replaced *)
-
- {Initialize new table with closed handles}
- NewTable := Ptr(DosMem.Sele, 0);(*1*)
- FillChar(NewTable^, Handles, $FF);(*1*)
-
- {Copy old table to new. Assume old table in PrefixSeg}
- OldTable := Ptr(PrefixSeg, MemW[PrefixSeg:$34]);
- OldSize := Mem[PrefixSeg:$32];
- move(OldTable^, NewTable^, OldSize);
-
- {Set new handle table size and pointer}
- Mem[PrefixSeg:$32] := Handles;
- MemW[PrefixSeg:$34] := 0;
- MemW[PrefixSeg:$36] := DosMem.Segm;
- end; (* of DPMIExtendHandles *)
- {$ENDIF} {of IFNDEF MSDOS}
-
-
- (* deleted(6) DOS 2.11 Ver ... *)
- (*
- {$F+}
- procedure ExitHandler;
- {$F-}
- { Uninstall the extended handles interrupt. All files (other
- than standard handles) should be closed before unit exits. }
- begin
- ExitProc := ExitSave; { Chain to next exit
- routine }
- SwapVectorsExtend { Restore original
- interrupt vectors }
- end;
- *)
- (* END of delted(6) *)
-
- begin (* of Install *)
- (* deleted(7) DosVer 2.11 ... *)
- (* ExitSave := ExitProc; { Remember the
- previous exit routine }
- ExitProc := @ExitHandler; { Install our exit routine }
- *)
- (* END of delted(7) *)
-
-
- {$IFDEF MSDOS}
- MSDOSExtendHandles; { Enable the extra handles }
- {$ELSE}
- DPMIExtendHandles;
- {$ENDIF}
- end.
- {-------------------------------snapp--------------------------------}
-
- {-------------------------------snipp-------------------------------}
- unit DosMem;
-
- {$IFDEF DPMI} *** Only Real-Mode! *** {$ENDIF}
- {$IFDEF WINDOWS} *** Only Dos-Real-Mode *** {$ENDIF}
- {$IFDEF OS2} *** Only Dos-Real-Mode *** {$ENDIF}
-
- { This unit allows you to allocate memory from the DOS memory pool
- rather than
- from the Turbo Pascal heap. It also provides a procedure for
- shrinking the
- current program to free up DOS memory.
-
- Scott Bussinger
- Professional Practice Systems
- 110 South 131st Street
- Tacoma, WA 98444
- (206)531-8944
- Compuserve [72247,2671] }
-
- { ** Revision History **
- 1 SHRINK.PAS 15-Sep-89,`SCOTT' Initial version of SHRINK unit
- 2 SHRINK.PAS 19-Oct-90,`SCOTT'
- Added support for Turbo Pascal 6's new heap manager
- ** Revision History ** }
-
- interface
-
- procedure DosNew(var P: pointer;
- Bytes: word);
- { Get a pointer to a chunk of memory from DOS. Returns NIL if
- sufficient DOS memory is not available. }
-
- procedure DosDispose(var P: pointer);
- { Return an allocated chunk of memory to DOS. Only call this
- function
- with pointers allocated with DosNew or DosNewShrink. }
-
- procedure DosNewShrink(var P: pointer;
- Bytes: word);
- { Get a pointer to a chunk of memory from DOS, shrinking current
- program
- to gain DOS memory if necessary. Returns NIL if sufficient DOS
- memory
- is not available and there is insufficient free space in the heap
- to
- allow program to be shrunk to accomodate the request. }
-
- function Linear(P: pointer): longint;
- { Return the pointer as a linear longint value }
-
- implementation
-
- uses Dos;
-
- const DosOverhead = 1; { Extra number of
- paragraphs that DOS requires in overhead for MCB chain }
-
- function Linear(P: pointer): longint;
- { Return the pointer as a linear longint value }
- begin
- Linear := (longint(seg(P^)) shl 4) + ofs(P^)
- end;
-
- procedure DosNew(var P: pointer;
- Bytes: word);
- { Get a pointer to a chunk of memory from DOS. Returns NIL if
- sufficient DOS memory is not available. }
- var SegsToAllocate: word;
- Regs: Registers;
- begin
- SegsToAllocate := (Bytes+15) shr 4; { DOS allocates
- memory in paragraph sized pieces only }
- with Regs do
- begin
- AH := $48;
- BX := SegsToAllocate;
- MsDos(Regs);
- if odd(Flags)
- then
- P := nil { No memory
- available }
- else
- P := ptr(AX,$0000) { Return pointer to
- memory block }
- end
- end;
-
- procedure DosDispose(var P: pointer);
- { Return an allocated chunk of memory to DOS. Only call this
- function
- with pointers allocated with DosNew or DosNewShrink. }
- var Regs: Registers;
- begin
- with Regs do
- begin
- AH := $49;
- ES := seg(P^);
- MsDos(Regs)
- end
- end;
-
- procedure DosNewShrink(var P: pointer;
- Bytes: word);
- { Get a pointer to a chunk of memory from DOS, shrinking current
- program
- to gain DOS memory if necessary. Returns NIL if sufficient DOS
- memory
- is not available and there is insufficient free space in the heap
- to
- allow program to be shrunk to accomodate the request. }
- var BytesToAllocate: word;
- Regs: Registers;
- begin
- BytesToAllocate := (((Bytes+15) shr 4) + DosOverhead) shl 4;
- DosNew(P,Bytes);
- { Try to get memory the easy way first }
-
- {$IFDEF VER60} {$DEFINE NEWHEAP} {$ENDIF}
- {$IFDEF VER70} {$DEFINE NEWHEAP} {$ENDIF}
-
- {$IFDEF NEWHEAP}
- { Check for Turbo 6's new heap manager }
- if (P=nil) and (Linear(HeapEnd)-Linear(HeapPtr)>=BytesToAllocate)
- then
- begin
- { The easy method didn't work but there is sufficient space in
- the heap }
- dec(longint(HeapEnd),longint(BytesToAllocate) shl 12);
- { Move the top of the heap down }
-
- with Regs do
- begin
- AH := $4A;
- BX := seg(HeapEnd^) - prefixseg - (BytesToAllocate shr 4);
- ES := prefixseg;
- MsDos(Regs)
- end;
- DosNew(P,Bytes)
- { Try the DOS allocation one more time }
- end
- {$ELSE}
- if (P=nil) and
- { Handle the old free list style heap }
- ( ( (ofs(FreePtr^)=0)
- and (Linear(FreePtr)+$10000-Linear(HeapPtr)>=BytesToAllocate)
- ) or
- (
- (ofs(FreePtr^)<>0)
- and (Linear(FreePtr)-Linear(HeapPtr)>=BytesToAllocate)
- ) )
- then
- begin
- { The easy method didn't work but there is sufficient space in
- the heap }
- OldFreePtr := FreePtr;
- dec(longint(FreePtr),longint(BytesToAllocate) shl 12);
- { Decrement the segment of the pointer to the free list }
-
- if ofs(OldFreePtr^) <> 0 then
- { If free list is empty, then there's nothing to move }
- move(OldFreePtr^,FreePtr^,$10000-ofs(OldFreePtr^));
- { Otherwise, move the free list down in memory }
-
- with Regs do
- begin
- AH := $4A;
- BX := seg(OldFreePtr^) + $1000 - prefixseg - (BytesToAllocate
- shr 4);
- ES := prefixseg;
- MsDos(Regs)
- end;
- DosNew(P,Bytes) { Try the DOS
- allocation one more time }
- end
- {$ENDIF}
- {$IFDEF NEWHEAP}{$UNDEF NEWHEAP}{$ENDIF}
- end;
-
- end.